

;(function($){


	$.fn.clone =  function () {
		
		var ret = $()
		$.extend(ret, this)
		return ret;
	}

	$.fn.carousel = function(obj) {
		return new Carousel(obj);
	}

	var cache ={} , index = 0 ,timer = null , delayTime = 0, loop = false;	
	function Carousel(obj) {
		this.props =  {
			effect: 'left',
			delayTime: 3000,
			loop: false,
			autoPlay: false
		};
		
		this.init(obj);
	}
	Carousel.prototype ={
		init: function(obj) {
			clearInterval(timer);	//清除以前动画

			$.extend(this.props,obj);

			index = 0;		// 初始化下标
			
			//一些判定参数
			var auto = this.props.autoPlay, effect = this.props.effect;
			loop = this.props.loop;

			delayTime = this.props.delayTime;
			if( effect === 'left' ) {		//把用户输入的间隔时间加上动画所需时间
				delayTime = +delayTime+500;
			}else {
				delayTime = +delayTime+200;
			}

			//获取必要dom
			var $oCarousel = $('.xu-carousel'),	//总idv
				$oCarouselBody = $('.xu-carousel-body'),	//主题部分
				$img = $('.xu-carousel-body img'),		//图片
				$lis = $('.xu-carousel-body li'),		//li
				$mark = $('.xu-carousel-mark li');		//下标标志

			//需要的全局dom对象，其他方法中需要用到
			this.elems ={
				$mark: $mark,
				$lis: $lis,
				$img: $img,
				$oCarouselBody: $oCarouselBody
			}

			//第一次初始化时缓存一些固定数据
			if(!$.data(cache,'imgHeight') ) {

				$.data(cache,'imgWidth',$img.width());
				$.data(cache,'imgHeight',$img.height());
				$.data(cache,'imgCount',$lis.length);
				$.data(cache,'lis',$lis.clone());
				//第一次初始化时，设置总div宽高
				$oCarousel.width( $.data(cache,'imgWidth') ).height($.data(cache,'imgHeight'));	
			}
			//读取img宽高
			var imgWidth = $.data(cache,'imgWidth'),
				imgHeight = $.data(cache,'imgHeight'),
				imgCount = $.data(cache,'imgCount');

			//初始化参数，必须的，在修改参数后需重置各个css样式
			$mark.first().addClass('active').siblings().removeClass('active');
			$oCarouselBody.css('left','0');	
			
			//存放Carousel上下文
			var self = this;

			//关闭所有可能定义过的事件
			$('.xu-carousel>a').off('click');
			$mark.off('mouseenter').off('mouseleave').off('click');

			//根据不同动画设置参数
			if( effect === 'fade' ) {
				//初始化dom和css，必须的，在修改参数后把dom结构重置为fade模式
				$oCarouselBody.width( imgWidth );
				$lis = $.data(cache,'lis')
				$oCarouselBody.html( $lis );
				$lis.first().show().siblings().hide();

				//设置fade事件
				$mark.hover(function(){	
					clearInterval(timer);
					index = $(this).index();
					self.fadeAnimate();
					
				},function() {
					if( auto ) {			//如果是自动播放，在鼠标离开后重启定时器
						timer = setInterval(function(){
							self.forward();
						},delayTime);
					}
					
				});
				
				$('.xu-carousel .xu-prev').on('click',function() {
					self.back();
					if( auto ) {
						clearInterval(timer);
						timer = setInterval(function(){
							self.forward();
						},delayTime);
					}

					
				})
				$('.xu-carousel .xu-next').on('click', function(e) {
					self.forward();
					if( auto ) {
						clearInterval(timer);
						timer = setInterval(function(){
							self.forward();
						},delayTime);
					}
					
				})
			}else if( effect === 'left') {

				//初始化dom结构
				$lis.show();	//初始化用，如果上一次为fade动画，那么需将所有li都显示
				if( !loop ) {
					//非循环滑动 , 初始化dom和css
					$oCarouselBody.html( $.data(cache,'lis'));
					$oCarouselBody.css({
						left: 0,
						width: imgWidth*imgCount+'px'
					});
				}else {
					//循环滑动，初始化dom和css （li个数翻倍）
					$oCarouselBody.html( $.data(cache,'lis') );
					$oCarouselBody.append(  $lis.clone() );
					index = imgCount;	//循环的初始坐标
					$oCarouselBody.css({
						left: -imgCount*imgWidth + 'px',
						 width: imgWidth*imgCount*2 +'px'
					});
			
				}

				//配置滑动事件
				$mark.on('click',function(){
					if( auto ) {
						clearInterval(timer);
						timer = setInterval(function() {
							self.forward();
						},delayTime);
					}
					index = $(this).index();
					if( loop ) {
						index += imgCount;
					}
					self.slideAnimate();
				});

				$('.xu-carousel .xu-prev').on('click',function() {
					self.back();
					if(  auto ) {
						clearInterval(timer);
						timer = setInterval(function(){
							self.forward();
						},delayTime);
					}
					
				})
				$('.xu-carousel .xu-next').on('click', function() {
					self.forward();
					if( auto ) {
						clearInterval(timer);
						timer = setInterval(function(){
							self.forward();
						},delayTime);
					}
				
				});
				
			}
			if( auto) {
				this.autoPlay();
			}
			this.setting = false;

		},
		set: function(obj) {
			this.init(obj);
		},
		//后退
		back: function() {
			var imgCount = $.data(cache,'imgCount');
			if( this.setting ) {
				return;
			}
			if( this.props.effect === 'fade' ) {
				if( --index < 0 ) {
					index = imgCount-1;
				}
				this.fadeAnimate();
			}else {
				if( loop ) {
					index--;
					this.slideAnimate();
				}else {
					if( --index === -1 ) {
						index = imgCount-1;
					}
					this.slideAnimate();
				}
			}
		},
		//前进
		forward: function() {
			var imgCount = $.data(cache,'imgCount');
			if( this.setting ) {
				return;
			}
			if( this.props.effect === 'fade' ) {
				if( ++index === imgCount ) {
					index = 0;
				}
				this.fadeAnimate();
			}else if( this.props.effect === 'left' ) {
				if( loop ) {
					index++;
					this.slideAnimate();
				}else {
					if( ++index === imgCount ) {
						index = 0;
					}
					this.slideAnimate();
				}
			}
		},

		autoPlay: function() {
			var self = this;
			timer = setInterval(function(){
				self.forward();
			},delayTime);
		},

		//淡入淡出动画
		fadeAnimate: function() {
			var $mark = this.elems.$mark, $lis = this.elems.$lis;

			$mark.eq( index ).addClass('active').siblings().removeClass('active');
			$lis.eq(index).fadeIn(200).siblings().hide();
		},
		//滑动动画
		slideAnimate: function() {
			if( this.setting  ) {
				return;
			}
			this.setting = !this.setting;
			var self = this,  imgCount = $.data(cache,'imgCount') , step = $.data(cache,'imgWidth');
			var $oCarouselBody = this.elems.$oCarouselBody, $mark = this.elems.$mark;

			$mark.eq( index%imgCount ).addClass('active').siblings().removeClass('active');

			$oCarouselBody.animate({
				left: -index*step
			},500,function() {
				//动画结束后，如果是循环滑动动画，需要重新配置下标
				if( loop ) {
					if( index === imgCount*2-1 ) {
						index = imgCount-1;
						$oCarouselBody.css('left',-index*step + 'px');
					}else if( index === 0 ) {
						index = imgCount;
						$oCarouselBody.css('left',-index*step + 'px');
					}
				}
				self.setting = false;
			})
		}

	}
})(window.jQuery || window.Xu)



